Import libraries
Link to Pandas Documentation: https://pandas.pydata.org/docs/index.html
Link to datareader Documentation: https://pandas-datareader.readthedocs.io/en/latest/index.html
Link to Yf Documentation: https://pandas-datareader.readthedocs.io/en/latest/readers/yahoo.html
Link to Plotly Documentation: https://plotly.com/python/
# !pip install pandas
# !pip install pandas-datareader
# !pip install yfinance
# !pip install datetime
# !pip install plotly_express
import pandas as pd
from pandas_datareader import data as pdr
import numpy as np
import yfinance as yf
import datetime as dt
import plotly.express as px
import plotly.graph_objects as go
# Define the start and end dates, last 5 years
end = dt.datetime.now()
start = end - dt.timedelta(days = 365*5)
# define Tickers
tk = input('Enter the ticker code: ')
tickers = [tk]
file_name = tk + ".csv"
yf.pdr_override()
Enter the ticker code: META
#obtain data and save as CSV
df = pdr.get_data_yahoo(tickers, start = start, end = end)
df.to_csv(file_name)
df.head(2)
[*********************100%%**********************] 1 of 1 completed
| Open | High | Low | Close | Adj Close | Volume | |
|---|---|---|---|---|---|---|
| Date | ||||||
| 2018-11-12 | 144.479996 | 145.039993 | 140.490005 | 141.550003 | 141.550003 | 18542100 |
| 2018-11-13 | 142.000000 | 144.880005 | 141.619995 | 142.160004 | 142.160004 | 15141700 |
#read CSV file
stock_df = pd.read_csv(file_name)
# Test for null values, and show info
stock_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1258 entries, 0 to 1257 Data columns (total 7 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Date 1258 non-null object 1 Open 1258 non-null float64 2 High 1258 non-null float64 3 Low 1258 non-null float64 4 Close 1258 non-null float64 5 Adj Close 1258 non-null float64 6 Volume 1258 non-null int64 dtypes: float64(5), int64(1), object(1) memory usage: 68.9+ KB
#insert 'Daily Return' column
stock_df['Daily Return'] = stock_df['Adj Close'].pct_change(1) * 100
# replace the first row, changes null for 0
stock_df['Daily Return'].replace(np.nan, 0, inplace = True)
stock_df
| Date | Open | High | Low | Close | Adj Close | Volume | Daily Return | |
|---|---|---|---|---|---|---|---|---|
| 0 | 2018-11-12 | 144.479996 | 145.039993 | 140.490005 | 141.550003 | 141.550003 | 18542100 | 0.000000 |
| 1 | 2018-11-13 | 142.000000 | 144.880005 | 141.619995 | 142.160004 | 142.160004 | 15141700 | 0.430944 |
| 2 | 2018-11-14 | 143.699997 | 145.580002 | 141.550003 | 144.220001 | 144.220001 | 22068400 | 1.449070 |
| 3 | 2018-11-15 | 142.330002 | 144.839996 | 140.830002 | 143.850006 | 143.850006 | 30320300 | -0.256549 |
| 4 | 2018-11-16 | 141.070007 | 141.770004 | 137.770004 | 139.529999 | 139.529999 | 37250600 | -3.003133 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1253 | 2023-11-06 | 315.980011 | 318.329987 | 314.450012 | 315.799988 | 315.799988 | 12887700 | 0.381431 |
| 1254 | 2023-11-07 | 317.059998 | 321.000000 | 315.119995 | 318.820007 | 318.820007 | 14055600 | 0.956308 |
| 1255 | 2023-11-08 | 318.140015 | 321.329987 | 314.880005 | 319.779999 | 319.779999 | 13609700 | 0.301108 |
| 1256 | 2023-11-09 | 319.420013 | 324.179993 | 318.799988 | 320.549988 | 320.549988 | 16103100 | 0.240787 |
| 1257 | 2023-11-10 | 319.940002 | 329.100006 | 319.459991 | 328.769989 | 328.769989 | 19096200 | 2.564343 |
1258 rows × 8 columns
stock_df.describe().round(2)
| Open | High | Low | Close | Adj Close | Volume | Daily Return | |
|---|---|---|---|---|---|---|---|
| count | 1258.00 | 1258.00 | 1258.00 | 1258.00 | 1258.00 | 1.258000e+03 | 1258.00 |
| mean | 230.41 | 233.76 | 227.30 | 230.55 | 230.55 | 2.376742e+07 | 0.11 |
| std | 69.13 | 69.66 | 68.45 | 69.07 | 69.07 | 1.560471e+07 | 2.78 |
| min | 90.08 | 90.46 | 88.09 | 88.91 | 88.91 | 6.046300e+06 | -26.39 |
| 25% | 178.24 | 180.40 | 176.29 | 178.09 | 178.09 | 1.505675e+07 | -1.16 |
| 50% | 213.19 | 216.04 | 210.51 | 213.33 | 213.33 | 2.012345e+07 | 0.11 |
| 75% | 288.38 | 292.74 | 284.33 | 288.26 | 288.26 | 2.797518e+07 | 1.43 |
| max | 381.68 | 384.33 | 378.81 | 382.18 | 382.18 | 2.323166e+08 | 23.28 |
Used Plotly Express for data visualization
# Define a function that performs interactive data visualization using Plotly Express
def plotly_data(df, title):
# Create figure
fig = go.Figure()
# Set title
fig.update_layout(title_text = title)
# For loop that plots all stock prices in the pandas dataframe df
# starts with 1, to skip the date column
for i in df.columns[1:]:
# Add range slider
fig.update_layout(xaxis=dict(rangeselector = dict(buttons=list([dict(count=1, label="1m", step="month", stepmode="backward"), dict(count=6, label="6m", step="month", stepmode="backward"), dict(count=1, label="YTD", step="year", stepmode="todate"), dict(count=1, label="1y", step="year", stepmode="backward"), dict(step="all")])), rangeslider=dict( visible=True), type="date"))
# Add line graph
fig.add_scatter(x = df['Date'], y = df[i], name = i)
# Update Layout
fig.update_layout({'plot_bgcolor': "white"})
fig.show()
# Ploting AdjClose
plotly_data(stock_df.iloc[:, [0 , 5]], (tk + ' - Ajusted Closing Price[$]'))
# Ploting Trade Volume
plotly_data(stock_df.iloc[:, [0 , 6]], (tk +' - Trading Volume'))
# Ploting Percentage Daily Return
plotly_data(stock_df.iloc[:, [0 , 7]], (tk +' - Percentage Daily Return [%]'))